package data;

import images.PicsResize;
import jxl.read.biff.BiffException;
import obj.Item;
import util.Helper;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.*;
import java.util.*;

public class ExtramobiNew {
    public static int catCount = 0;
    public static int counter = 0;

    public static final String OUT_FOLDER = "data/import/extramobi/";
    public static final String PICS_PATH = "http://extramobi.ru/published/publicdata/EXTRAMOBI/attachments/SC/products_pictures/";
    //    public static final String OUT_FOLDER = "data/import/test/";
    public static final String DATA_FOLDER = "data/extramobi/";
    //    public static final String DATA_FOLDER = "data/test/";
    public static List<String> articles = new ArrayList<String>();

    private static Map<String, Integer> catSort = new HashMap<String, Integer>();
    public static Map<String, List<ModelItem>> modelItems;
    private static Map<String, Map<String, List<Item>>> allItems;
    private static Map<String, CSVData> catCache = new HashMap<String, CSVData>();
    private static Map<String, String> sortArticles = new HashMap<String, String>();

    private static List<String> invalidPicsList = new ArrayList<String>();
    private static Map<String, List<String>> origModels = new HashMap<String, List<String>>();

    public static Map<String, String> commonProps;
    private static final int COLUMNS = 2;
    //    private static final int ITEMS_PER_CAT = 2000;
    private static final int MODELS_LIMIT = 20;
    public static Sitemap sitemap;

    private static int subCategoryCount;

    public static String productUrl;
    public static String categoryUrl;
    //    public static final String IMPORT_FILE_ENCODING = "Windows-1251";
    public static final String IMPORT_FILE_ENCODING = "UTF-8";
    public static final int ITEMS_PER_CAT = 200;
    public static final int CAT_COUNT_STEP = 4000;
    private static int initCatCount = 0;

    static {
        try {
            commonProps = readCommonProps();
            productUrl = commonProps.get("common.product-url");
            categoryUrl = commonProps.get("common.category-url");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException, BiffException, JAXBException, InvalidImport, IllegalAccessException {
        initSitemap();
        File baseFolder = new File(DATA_FOLDER);
        initItems(baseFolder);
        System.out.println(allItems.size());
    }

    public static void main1(String[] args) throws IOException, BiffException, JAXBException, InvalidImport, IllegalAccessException {
        initSitemap();
        commonProps = readCommonProps();
        productUrl = commonProps.get("common.product-url");
        categoryUrl = commonProps.get("common.category-url");
        File baseFolder = new File(DATA_FOLDER);
        File[] folders = baseFolder.listFiles();
        initItems(baseFolder);
        for (File folder : folders) {
            if (folder.isDirectory() && !folder.getName().equals(".svn") && !folder.getName().equals("temp")) {
                String name = folder.getName();
                String[] brandFiles = folder.list();
                String propsFile = folder.getPath() + "\\" + name + ".properties";
                if (brandFiles.length > 0) {
                    for (String brandFile : brandFiles) {
                        List<String> processedModels = new ArrayList<String>();
                        System.out.println(brandFile);
                        List<Item> items;
                        if (brandFile.equals("remont.xls")) {
                            String path = folder.getPath() + "\\" + name + ".xls";
                            Map<String, List<Item>> itemsByBrand = Item.parseRemontItemsByBrand(path);
                            for (String brand : itemsByBrand.keySet()) {
                                items = itemsByBrand.get(brand);
                                processedModels = new ArrayList<String>();
                                printItems(propsFile, folder.getName(), items, processedModels);
                            }
                        } else if (brandFile.contains(folder.getName() + ".xls")) {
                            Map<String, List<ItemData>> data = ExtramobiExcel.parseItemData(folder.getPath() + "/" + brandFile);
                            for (String file : data.keySet()) {
                                PrintStream out = new PrintStream(new FileOutputStream(OUT_FOLDER + file));
                                out.println(CSVData.getHeader());
                                for (ItemData item : data.get(file)) {
                                    if (item.category) {
                                        putCatSort(item.name);
                                        item.sort = getSort(item.name);
                                    }
                                    Map<String, String> props = new HashMap<String, String>();
                                    props.put("item.order.list", getModelList(item.brand + " " + item.model));
                                    filterItem(item, commonProps, true);
                                    filterItem(item, props, false);
                                    item.sort = getSort(item.name, item.article);
                                    out.println(item);
                                }
                                out.close();
                            }
                        } else if (brandFile.endsWith(".xls")) {
                            items = Item.parseItemsXlsFile(folder.getPath() + "\\" + brandFile);
                            printItems(propsFile, folder.getName(), items, processedModels);
                        } else {
                            System.out.println("File missed: " + brandFile);
                        }
                    }
                }
//                initCatCount += CAT_COUNT_STEP;
            }
        }
//        ValidateImport.validate(OUT_FOLDER);
        printInvalidPics();
        printSitemap();
        System.out.println("the end");
        System.exit(0);
    }

    public static void filterItem(ItemData item, Map<String, String> props, boolean common) {
        for (String key : props.keySet()) {
            String value = props.get(key);
            if (common) {
                key = "\\#\\{" + key.replace(".", "\\.") + "\\}";
            } else {
                key = "\\$\\{" + key.replace(".", "\\.") + "\\}";
            }
            item.desc = item.desc.replaceAll(key, value);
            item.metadesc = item.metadesc.replaceAll(key, value);
            item.metakey = item.metakey.replaceAll(key, value);
            item.shortdesc = item.shortdesc.replaceAll(key, value);
            item.title = item.title.replaceAll(key, value);
        }
    }

    public static Map<String, String> readCommonProps(String commonPath) throws IOException {
        return DataHelper.readProps(DataHelper.Props.COMMON, commonPath);
    }

    public static Map<String, String> readCommonProps() throws IOException {
        return DataHelper.readProps(DataHelper.Props.COMMON, DATA_FOLDER + "common.properties");
    }

    private static void printInvalidPics() {
        System.err.println("Invalid pics list (" + invalidPicsList.size() + "): ");
        for (String pic : invalidPicsList) {
            System.err.println(pic);
        }
    }

    public static void printSitemap() throws JAXBException, FileNotFoundException {
        JAXBContext jaxbContext = JAXBContext.newInstance(Sitemap.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(sitemap, new FileOutputStream(OUT_FOLDER + "sitemap.xml"));
    }

    private static void initSitemap() throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(Sitemap.class);
        sitemap = (Sitemap) jaxbContext.createUnmarshaller().unmarshal(new File("data/extramobi/sitemap-template.xml"));

        for (Sitemap.Url url : sitemap.urls) {
            url.setLastmod();
        }
    }

    private static void printItems(String propsFile, String folderName, List<Item> items, List<String> processedModels) throws IOException, JAXBException {
        String header = CSVData.getHeader();
        Map<String, String> props = DataHelper.readProps(DataHelper.Props.CATEGORY, propsFile);
        String brand = items.get(0).props.get(Item.HEADER_PRODUCER);
        if (brand == null) {
            brand = items.get(0).brand;
        }
        PrintStream out = new PrintStream(new FileOutputStream(OUT_FOLDER + folderName + "-" + brand + ".txt"), false, IMPORT_FILE_ENCODING);
        out.println(header);
        Map<String, String> templates = createTemplateProps();
        props = filterProps(props, templates);
//        int initCatCount = Integer.parseInt(props.get("category.sort"));
//        int itemsPerCat = Integer.parseInt(props.get("category.itemspercat"));
//        int itemsPerCat = ITEMS_PER_CAT;
//        catCount = initCatCount;
        putCatSort(props.get("category.name"));
        printRecord(DataHelper.Props.CATEGORY, props, out);
        String currBrand = null;
        for (Item item : items) {
            processOrig(item);
            brand = item.props.get(Item.HEADER_PRODUCER);
            if (brand == null) {
                brand = item.brand;
            }
            if (currBrand == null || !currBrand.equals(brand)) {
                templates.put("\\$\\{brand\\.url\\}", brand);
                templates.put("\\$\\{brand\\.name\\}", brand);
                props = DataHelper.readProps(DataHelper.Props.CATEGORY_BRAND, propsFile);
                props = filterProps(props, templates);
//                catCount = initCatCount + ITEMS_PER_CAT * brandFileCount;
//                catCount = initCatCount + itemsPerCat * brandFileCount;
                putCatSort(props.get("category.brand.name"));
                printRecord(DataHelper.Props.CATEGORY_BRAND, props, out);
                currBrand = brand;
            }

            if (processedModels.contains(item.name.toLowerCase().trim())) {
                System.out.println("Already processed: " + item.name);
                continue;
            } else {
                processedModels.add(item.name.toLowerCase().trim());
            }
            props = DataHelper.readProps(DataHelper.Props.ITEM, propsFile);
            props.put(DataHelper.Props.ITEM.name + ".art", item.article);

            if (!brand.equals(item.brand)) {
                item.name = item.name.replace(item.brand, brand + " " + item.brand);
            }

            templates.put("\\$\\{item\\.mah\\}", getMah(item.props));
            filterProp(props, "item.name", "\\$\\{item\\.mah\\}", getMah(item.props));
//            filterProp(props, "item.name", "\\$\\{item\\.name\\}", item.name);
            templates.put("\\$\\{item\\.name\\}", item.name);
            templates.put("\\$\\{brand\\.name\\.translit\\}", Helper.translit(item.brand));
            templates.put("\\$\\{item\\.name\\.url\\}", item.name);
            templates.put("\\$\\{item\\.vendor\\}", brand);
            templates.put("\\$\\{item\\.props\\}", getPropsList(item.props));
            templates.put("\\$\\{model\\.titlelist\\}", getTitleList(item.models));
            templates.put("\\$\\{model\\.shortlist\\}", getShortList(item.models));
            templates.put("\\$\\{model\\.reflist\\}", getRefList(item, props));
            templates.put("\\$\\{item\\.order\\.list\\}", getModelList(item.name));
            props = filterProps(props, templates);
            if (item.models != null && item.name.equals(brand + " " + item.models.get(0))) {
                // not print
            } else {
                printRecord(DataHelper.Props.ITEM, props, out, item);
            }

//            for (Item item : items) {
            if (item.models != null && item.models.size() > 0) {
//                boolean itemEqualsModel;
//                if (brand.equals(item.brand)) {
//                    itemEqualsModel = item.models.size() == 1 && item.name.equalsIgnoreCase(item.brand + " " + item.models.get(0));
//                } else {
//                    itemEqualsModel = item.models.size() == 1 && item.name.equalsIgnoreCase(brand + " " + item.brand + " " + item.models.get(0));
//                }
//                if (itemEqualsModel) {
//                    continue;
//                }
                for (String model : item.models) {
//                    if (item.name.equals(brand + " " + model)) {
//                        continue;
//                    }
//                    int idx = item.models.indexOf(model);
                    if (processedModels.contains(model.toLowerCase().trim())) {
                        System.out.println("Already processed: " + brand + " " + model);
                        continue;
                    } else {
                        processedModels.add(model.toLowerCase().trim());
                    }
                    props = DataHelper.readProps(DataHelper.Props.ITEM_MODEL, propsFile);
                    props.put(DataHelper.Props.ITEM_MODEL.name + ".art", item.article);

                    String modelName;
                    if (brand.equals(item.brand)) {
                        modelName = brand + " " + model;
                    } else {
                        modelName = brand + " " + item.brand + " " + model;
                    }
                    templates.put("\\$\\{item\\.name\\}", item.name);
                    templates.put("\\$\\{item\\.name\\.url\\}", item.name);
                    templates.put("\\$\\{brand\\.name\\.translit\\}", Helper.translit(item.brand));
                    templates.put("\\$\\{model\\.name\\}", modelName);
                    filterProp(props, "item.model.name", "\\$\\{item\\.mah\\}", getMah(item.props));
//                    filterProp(props, "item.model.name", "\\$\\{model\\.name\\}", getMah(item.props));
                    templates.put("\\$\\{model\\.url\\}", modelName);
                    templates.put("\\$\\{model\\.order\\.list\\}", getModelList(item.brand + " " + model));
                    props = filterProps(props, templates);
                    printRecord(DataHelper.Props.ITEM_MODEL, props, out, item);
                }
//                }
            }
        }
        out.close();
    }

    public static void filterProp(Map<String, String> props, String propToFilter, String template, String value) {
        String oldValue = props.get(propToFilter);
        String newValue = filterProp(oldValue, template, value);
        props.put(propToFilter, newValue);
    }

    public static String getMah(Map<String, String> props) {
        if (props.containsKey("Емкость")) {
            return props.get("Емкость");
        } else {
            return "";
        }
    }

    private static void printRecord(DataHelper.Props propsPrefix, Map<String, String> props, PrintStream out, Item item) throws JAXBException {
        CSVData data = null;
        String category = propsPrefix.name;
        String name = props.get(category + ".name");
        boolean isCategory = propsPrefix.equals(DataHelper.Props.CATEGORY) || propsPrefix.equals(DataHelper.Props.CATEGORY_BRAND);
        if (isCategory) {
            if (catCache.containsKey(name)) {
                data = catCache.get(name);
            }
        }

        if (data == null) {
            data = new CSVData();
            data.art = props.get(category + ".art") == null ? "" : props.get(category + ".art");
            data.engname = props.get(category + ".engname");
            data.name = name;
            data.id = props.get(category + ".id");
            data.desc = props.get(category + ".desc");
            data.shortDesc = props.get(category + ".shortdesc");
            String article = item == null ? null : item.article;
            data.sort = getSort(data.name, article);
            data.title = props.get(category + ".title");
            data.metaKeywords = props.get(category + ".metakeywords");
            data.metaDesc = props.get(category + ".metadesc");
            String photo = props.get(category + ".photo");
//            String photo2 = props.get(category + ".photo2");
//            data.picture = photo == null ? "" : photo;
//            data.picture2 = photo2 == null ? "" : photo2;
            data.pics = photo == null ? "" : photo;
            if (data.pics.contains(",")) {
                String[] fields = data.pics.split("\\,");
                for (String field : fields) {
                    if (!PicsResize.getProductPictures().contains(field) && !invalidPicsList.contains(field)) {
                        addToInvalidPicsList(field);
                    }
                }
            } else if (data.pics.length() > 0) {
                if (!PicsResize.getProductPictures().contains(data.pics) && !invalidPicsList.contains(data.pics)) {
                    addToInvalidPicsList(data.pics);
                }
            }
            if (item != null) {
                data.price = item.price + "";
                data.oldPrice = item.oldPrice + "";
                data.count = item.count + "";
            }
        }
        out.println(data);
        if (isCategory && !catCache.containsKey(name)) {
            catCache.put(name, data);
            String url = categoryUrl + data.id;
            addToSitemap(url);
        }
    }

    private static void addToInvalidPicsList(String field) {
        String picName = field.replace("-large", "");
        picName = picName.replace("-medium", "");
        picName = picName.replace("-small", "");
        if (!invalidPicsList.contains(picName)) {
            invalidPicsList.add(picName);
        }
    }

    public static void initItems(File baseFolder, boolean processSitemap) throws BiffException, IOException, IllegalAccessException, JAXBException {
        modelItems = new TreeMap<String, List<ModelItem>>();
        allItems = new TreeMap<String, Map<String, List<Item>>>();
        File[] folders = baseFolder.listFiles();
        for (File folder : folders) {
            if (folder.isDirectory() && !folder.getName().equals(".svn") && !folder.getName().equals("temp")) {
                String name = folder.getName();
                String[] brandFiles = folder.list();
                String propsFile = folder.getPath() + "\\" + name + ".properties";
                Map<String, String> itemProps = DataHelper.readProps(DataHelper.Props.ITEM, propsFile);
                Map<String, String> itemModelProps = DataHelper.readProps(DataHelper.Props.ITEM_MODEL, propsFile);
                if (brandFiles.length > 1) {
                    for (String brandFile : brandFiles) {
//                        if (brandFile.endsWith(".properties") || brandFile.endsWith(".svn")) {
//                            continue;
//                        } else
                        if (brandFile.equals("remont.xls")) {
                            List<Item> items = Item.parseRemontItems(folder.getPath() + "\\" + name + ".xls");
                            for (Item item : items) {
                                ModelItem modelItem = new ModelItem();
                                modelItem.count = 1;
                                modelItem.price = 0;
                                modelItem.modelName = item.name.toLowerCase().trim();
                                modelItem.brandName = item.brand;
                                modelItem.url = productUrl + filterProp(itemProps.get("item.id"), "\\$\\{item\\.name\\.url\\}", item.name);
                                if (processSitemap) {
                                    addToSitemap(modelItem.url);
                                }
                                filterProp(itemModelProps, "item.name", "\\$\\{item\\.mah\\}", getMah(itemModelProps));
                                modelItem.name = filterProp(itemProps.get("item.name"), "\\$\\{item\\.name\\}", item.name);
                                putModelItem(modelItem);
                            }
                        } else if (brandFile.equals(folder.getName() + ".xls")) {
                            Map<String, List<ItemData>> itemsByBrand = ExtramobiExcel.parseItemData(folder.getPath() + "/" + brandFile);
                            for (String brand : itemsByBrand.keySet()) {
                                for (ItemData item : itemsByBrand.get(brand)) {
                                    if (item.category || !item.popular) {
                                        continue;
                                    }
                                    ModelItem modelItem = new ModelItem();
                                    modelItem.modelName = (item.brand + " " + item.model).toLowerCase().trim();
                                    modelItem.brandName = item.brand;
                                    modelItem.count = item.count;
                                    modelItem.price = item.price;
                                    modelItem.url = productUrl + item.url;
                                    modelItem.name = item.name;
                                    if (processSitemap) {
                                        addToSitemap(modelItem.url);
                                    }
                                    putModelItem(modelItem);
                                }
                            }
                            System.out.println();
                        } else if (brandFile.endsWith(".xls")) {
                            List<Item> items = Item.parseItemsXlsFile(folder.getPath() + "\\" + brandFile);
                            for (Item item : items) {
                                processOrig(item);
                                checkArticle(item);
                                if (item.models != null) {
                                    for (String model : item.models) {
                                        String brand = item.props.get(Item.HEADER_PRODUCER);
                                        if (brand != null && !brand.equals(item.brand)) {
                                            brand = brand + " " + item.brand;
                                        } else {
                                            brand = item.brand;
                                        }
                                        ModelItem modelItem = new ModelItem();
                                        modelItem.modelName = (item.brand + " " + model).toLowerCase().trim();
                                        modelItem.brandName = item.brand;
                                        modelItem.count = item.count;
                                        modelItem.price = item.price;
                                        modelItem.url = productUrl + filterProp(itemModelProps.get("item.model.id"), "\\$\\{model\\.url\\}", brand + " " + model);
                                        if (processSitemap) {
                                            addToSitemap(modelItem.url);
                                        }
                                        filterProp(itemModelProps, "item.model.name", "\\$\\{item\\.mah\\}", getMah(itemModelProps));
                                        modelItem.name = filterProp(itemModelProps.get("item.model.name"), "\\$\\{model\\.name\\}", brand + " " + model);
                                        putModelItem(modelItem);
                                    }
                                } else {
                                    ModelItem modelItem = new ModelItem();
                                    modelItem.modelName = item.name.toLowerCase().trim();
                                    modelItem.brandName = item.brand;
                                    modelItem.count = item.count;
                                    modelItem.price = item.price;
                                    modelItem.url = productUrl + filterProp(itemProps.get("item.id"), "\\$\\{item\\.name\\.url\\}", item.name);
                                    if (processSitemap) {
                                        addToSitemap(modelItem.url);
                                    }
                                    modelItem.name = filterProp(itemProps.get("item.name"), "\\$\\{item\\.name\\}", item.name);
                                    putModelItem(modelItem);
                                }
                            }
                        }
                    }
                }
            }
        }
//        return modelItems;
    }

    public static void processOrig(Item item) {
        if (item.props.containsKey("Оригинальный")) {
            if (Boolean.parseBoolean(item.props.get("Оригинальный"))) {
                origModels.put(item.name, item.models);
            } else {
                if (origModels.containsKey(item.name)) {
                    item.models = origModels.get(item.name);
                } else {
                    System.out.println("No Original models: " + item.name);
                }
            }
        }
    }

    public static void processOrig(ItemData item) {
        if (item.original.equals(Orig.NOT_ORIGINAL)) {
            item.models = origModels.get(item.brand + " " + item.model);
            if (item.models == null) {
                throw new IllegalStateException("OrigModels does not contain " + item.brand + " " + item.model);
            }
        }
    }

    public static void processOrig(ItemData item, Map<String, String> props) {
        if (props.containsKey("Оригинальный") && !item.category) {
            if (Boolean.parseBoolean(props.get("Оригинальный"))) {
                origModels.put(item.brand + " " + item.model, item.models);
                item.original = Orig.ORIGINAL;
            } else {
                item.original = Orig.NOT_ORIGINAL;
                if (origModels.containsKey(item.brand + " " + item.model)) {
                    item.models = origModels.get(item.brand + " " + item.model);
                } else {
                    System.out.println("No Original models: " + item.brand + " " + item.model);
                }
            }
        } else {
            item.original = Orig.NOT_SET;
        }
    }

    public static void initItems(File baseFolder) throws BiffException, IOException, IllegalAccessException, JAXBException {
        initItems(baseFolder, true);
    }

    public static void addToSitemap(String url) throws JAXBException {
        if (sitemap == null) {
            initSitemap();
        }
        Sitemap.Url sitemapUrl = new Sitemap.Url(url);
        if (!sitemap.urls.contains(sitemapUrl)) {
            sitemap.urls.add(sitemapUrl);
        } else {
            System.out.println("URL already added: " + url);
        }
    }

    private static void checkArticle(Item item) {
        if (item.article.length() != 7) {
            throw new IllegalArgumentException("Out of Article length: " + item);
        }
//        if (articles.contains(item.article)) {
//            throw new IllegalArgumentException("Not unique Article: " + item);
//        }
        articles.add(item.article);
    }

    public static void putModelItem(ModelItem modelItem) {
        if (modelItems == null) {
            modelItems = new TreeMap<String, List<ModelItem>>();
        }
        List<ModelItem> modelItemsList;
        if (modelItems.containsKey(modelItem.modelName)) {
            modelItemsList = modelItems.get(modelItem.modelName);
        } else {
            modelItemsList = new ArrayList<ModelItem>();
        }
        if (!modelItemsList.contains(modelItem)) {
            modelItemsList.add(modelItem);
        } else {
            System.out.println("ModelItem exists: " + modelItem);
        }
        modelItems.put(modelItem.modelName, modelItemsList);
    }

    public static String getModelList(String brandModel) {
        List<ModelItem> modelItemList = modelItems.get(brandModel.toLowerCase().trim());
        if (modelItemList != null) {
            StringBuilder sb = new StringBuilder("<ul>");
            for (ModelItem modelItem : modelItemList) {
                sb.append("<li class=\"parent\">").append("<a style=\"font-weight:bold\" " +
                        "onmouseover=\"document.getElementById('" + modelItem.article + "').style.display='inline'\"" +
                        "onmouseout=\"document.getElementById('" + modelItem.article + "').style.display='none'\" href=\"").
                        append(modelItem.url).append("\">").append(modelItem.name).append("</a>").
                        append("<img id=\"").append(modelItem.article).append("\" src=\"").append(PICS_PATH + modelItem.imgUrl).append("\" style=\"display:none;position:absolute\"/>").
                        append(" за <span style=\"color:red\">").
                        append(modelItem.price).append(" руб.</span></li>");
            }
            sb.append("</ul>");
            return sb.toString();
        } else {
            return "";
        }
    }
//    public static String getModelList(String brandModel) {
//        List<ModelItem> modelItemList = modelItems.get(brandModel.toLowerCase().trim());
//        if (modelItemList != null) {
//            StringBuilder anchors = new StringBuilder("<table><tr style=\"vertical-align:top\"><td><ul>");
//            StringBuilder images = new StringBuilder("<td>");
//            for (ModelItem modelItem : modelItemList) {
//                anchors.append("<li class=\"parent\">").append("<a style=\"font-weight:bold\" " +
//                        "onmouseover=\"document.getElementById('" + modelItem.article + "').style.display='block'\"" +
//                        "onmouseout=\"document.getElementById('" + modelItem.article + "').style.display='none'\" href=\"").
//                        append(modelItem.url).append("\">").append(modelItem.name).append("</a> за <span style=\"color:red\">").
//                        append(modelItem.price).append(" руб.</span></li>");
//                images.append("<img id=\"").append(modelItem.article).append("\" src=\"").append(PICS_PATH + modelItem.imgUrl).append("\" style=\"display:none;position:absolute\"/>");
//            }
//            images.append("</td>");
//            anchors.append("</ul></td style=\"padding: 5px 5px 5px 5px\">");
//            anchors.append(images).append("</tr></table>");
//            return anchors.toString();
//        } else {
//            return "";
//        }
//    }


    public static String getRefList(ItemData item) {
        String brand = item.brand;
//        String brand = item.props.get(Item.HEADER_PRODUCER);
//        if (brand != null && !item.brand.equals(brand)) {
//            brand = brand + " " + item.brand;
//        } else {
//            brand = item.brand;
//        }
        if (item.models == null) {
            return "";
        } else if (item.models.size() > 5) {
            return getRefTable(item);
        }
        StringBuilder sb = new StringBuilder("<ul>");
        if (item.modelsData.size() > MODELS_LIMIT) {
            for (int i = item.modelsData.size() - 1; i > item.modelsData.size() - MODELS_LIMIT; i--) { // take the last models first
                String name = item.modelsData.get(i).name;
                String url = productUrl + item.modelsData.get(i).url;
                sb.append("<li><a href=\"").append(url).append("\">").append(name).append("</a></li>");
            }
        } else {
            for (ItemData model : item.modelsData) {
                String name = model.name;
                String url = productUrl + model.url;
                sb.append("<li><a href=\"").append(url).append("\">").append(name).append("</a></li>");
            }
        }
        sb.append("</ul><br/>");
        return sb.toString();
    }

    private static String getRefList(Item item, Map<String, String> props) {
        String brand = item.props.get(Item.HEADER_PRODUCER);
        if (brand != null && !item.brand.equals(brand)) {
            brand = brand + " " + item.brand;
        } else {
            brand = item.brand;
        }
        if (item.models == null) {
            return "";
        } else if (item.models.size() > 5) {
            return getRefTable(item, props);
        }
        StringBuilder sb = new StringBuilder("<ul>");
        if (item.models.size() > MODELS_LIMIT) {
            for (int i = item.models.size() - 1; i > item.models.size() - MODELS_LIMIT; i--) { // take the last models first
                String name = filterProp(props.get("item.name"), "\\$\\{item\\.name\\}", brand + " " + item.models.get(i));
                String url = productUrl + filterProp(props.get("item.id"), "\\$\\{item\\.name\\.url\\}", brand + " " + item.models.get(i));
                sb.append("<li><a href=\"").append(url).append("\">").append(name).append("</a></li>");
            }
        } else {
            for (String model : item.models) {
                String name = filterProp(props.get("item.name"), "\\$\\{item\\.name\\}", brand + " " + model);
                String url = productUrl + filterProp(props.get("item.id"), "\\$\\{item\\.name\\.url\\}", brand + " " + model);
                sb.append("<li><a href=\"").append(url).append("\">").append(name).append("</a></li>");
            }
        }
        sb.append("</ul><br/>");
        return sb.toString();
    }


    private static String getRefTable(Item item, Map<String, String> props) {
        if (item.models == null) {
            return "";
        }
        String brand = item.props.get(Item.HEADER_PRODUCER);
        if (brand != null && !item.brand.equals(brand)) {
            brand = brand + " " + item.brand;
        } else {
            brand = item.brand;
        }
        StringBuilder sb = new StringBuilder("<table>");
        int count = 0;
        if (item.models.size() > MODELS_LIMIT) {
            for (int i = item.models.size() - 1; i > item.models.size() - MODELS_LIMIT; i--) { // take the last models first
                count++;
                String name = filterProp(props.get("item.name"), "\\$\\{item\\.name\\}", brand + " " + item.models.get(i));
                String url = productUrl + filterProp(props.get("item.id"), "\\$\\{item\\.name\\.url\\}", brand + " " + item.models.get(i));
                if (count == 1 || (count % COLUMNS) - 1 == 0) {
                    sb.append("<tr>");
                }
                sb.append("<td style=\"padding:0 10 10 0\"><strong><a href=\"").append(url).append("\">").append(name).append("</a></strong></td>");
                if (count % COLUMNS == 0) {
                    sb.append("</tr>");
                }
            }
            if (sb.toString().endsWith("</td>")) {
                sb.append("<td><strong>...</strong></td></tr>");
            } else {
                sb.append("<tr><td><strong>...</strong></td></tr>");
            }
        } else {
            for (String model : item.models) {
                count++;
                String name = filterProp(props.get("item.name"), "\\$\\{item\\.name\\}", brand + " " + model);
                String url = productUrl + filterProp(props.get("item.id"), "\\$\\{item\\.name\\.url\\}", brand + " " + model);
                if (count == 1 || (count % COLUMNS) - 1 == 0) {
                    sb.append("<tr>");
                }
                sb.append("<td style=\"padding:0 10 10 0\"><strong><a href=\"").append(url).append("\">").append(name).append("</a></strong></td>");
                if (count % COLUMNS == 0) {
                    sb.append("</tr>");
                }
            }
            if (sb.toString().endsWith("</td>")) {
                sb.append("</tr>");
            }
        }
        sb.append("</table>");
        return sb.toString();
    }

    public static String getRefTable(ItemData item) {
        if (item.models == null) {
            return "";
        }
        String brand = item.props.get(Item.HEADER_PRODUCER);
        if (brand != null && !item.brand.equals(brand)) {
            brand = brand + " " + item.brand;
        } else {
            brand = item.brand;
        }
        StringBuilder sb = new StringBuilder("<table>");
        int count = 0;
        if (item.models.size() > MODELS_LIMIT) {
            for (int i = item.modelsData.size() - 1; i > item.modelsData.size() - MODELS_LIMIT; i--) { // take the last models first
                count++;
                String name = item.modelsData.get(i).name;
                String url = productUrl + item.modelsData.get(i).url;
                if (count == 1 || (count % COLUMNS) - 1 == 0) {
                    sb.append("<tr>");
                }
                sb.append("<td style=\"padding:0 10 10 0\"><strong><a href=\"").append(url).append("\">").append(name).append("</a></strong></td>");
                if (count % COLUMNS == 0) {
                    sb.append("</tr>");
                }
            }
            if (sb.toString().endsWith("</td>")) {
                sb.append("<td><strong>...</strong></td></tr>");
            } else {
                sb.append("<tr><td><strong>...</strong></td></tr>");
            }
        } else {
            for (ItemData model : item.modelsData) {
                count++;
                String name = model.name;
                String url = productUrl + model.url;
                if (count == 1 || (count % COLUMNS) - 1 == 0) {
                    sb.append("<tr>");
                }
                sb.append("<td style=\"padding:0 10 10 0\"><strong><a href=\"").append(url).append("\">").append(name).append("</a></strong></td>");
                if (count % COLUMNS == 0) {
                    sb.append("</tr>");
                }
            }
            if (sb.toString().endsWith("</td>")) {
                sb.append("</tr>");
            }
        }
        sb.append("</table>");
        return sb.toString();
    }

    public static String getShortList(List<String> models) {
        if (models == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        if (models.size() > MODELS_LIMIT) {
            for (int i = models.size() - 1; i > models.size() - MODELS_LIMIT; i--) { // take the last models first
                sb.append(", <strong>").append(models.get(i)).append("</strong>");
            }
            sb.append(", ...");
        } else {
            for (String device : models) {
                sb.append(", <strong>").append(device).append("</strong>");
            }
        }
        sb.deleteCharAt(0);
        return sb.toString();
    }

    public static String getTitleList(List<String> models) {
        if (models == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        if (models.size() > MODELS_LIMIT) {
            for (int i = models.size() - 1; i > models.size() - MODELS_LIMIT; i--) { // take the last models first
                sb.append(" ").append(models.get(i));
            }
        } else {
            for (String device : models) {
                sb.append(" ").append(device);
            }
        }
        sb.delete(0, 1);
        return sb.toString();
    }

    public static String getPropsList(Map<String, String> props) {
        if (props == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder("<table>");
        int row = 0;
        for (String key : props.keySet()) {
            row++;
            String value = props.get(key);
            if (value.isEmpty()) {
                continue;
            }
            String color = row % 2 == 0 ? "#faf7e6" : "";
            sb.append("<tr bgcolor=\"" + color + "\"><td>").append(key).append(": </td><td><strong>").append(value).append("</strong></td></tr>");
        }
        sb.append("</table>");
        return sb.toString();
    }

    public static Map<String, String> createTemplateProps(String commonPath) throws IOException {
        Map<String, String> templates = new HashMap<String, String>();
        if (commonProps == null) {
            commonProps = readCommonProps(commonPath);
        }
        for (String commonKey : commonProps.keySet()) {
            String value = commonProps.get(commonKey);
            commonKey = "\\#\\{" + commonKey.replace(".", "\\.") + "\\}";
            templates.put(commonKey, value);
        }
        return templates;
    }

    public static Map<String, String> createTemplateProps() throws IOException {
        Map<String, String> templates = new HashMap<String, String>();
        if (commonProps == null) {
            commonProps = readCommonProps();
        }
        for (String commonKey : commonProps.keySet()) {
            String value = commonProps.get(commonKey);
            commonKey = "\\#\\{" + commonKey.replace(".", "\\.") + "\\}";
            templates.put(commonKey, value);
        }
        return templates;
    }

    public static Map<String, String> filterProps(Map<String, String> props, Map<String, String> templates) {
        return DataGenerator.filterProps(props, templates);
    }

    private static String filterProp(String prop, String template, String value) {
        return DataGenerator.filterProp(prop, template, value);
    }

    private static void printRecord(DataHelper.Props propsPrefix, Map<String, String> props, PrintStream out) throws JAXBException {
        printRecord(propsPrefix, props, out, null);
    }

    public static void putCatSort(String cat) {
        if (!catSort.containsKey(cat)) {
            boolean highLevel = !cat.startsWith("!");
            if (highLevel) {
                if (catCount != 0) {
                    initCatCount += CAT_COUNT_STEP;
                }
                catCount = initCatCount;
                subCategoryCount = 0;
            } else {
                catCount = initCatCount + ITEMS_PER_CAT * subCategoryCount++;
            }
            catSort.put(cat, catCount);
            counter = catCount;
        }
    }

    public static String getSort(String cat, String article) {
        if (article == null) {
            return getSort(cat);
        }
        if (sortArticles.containsKey(article)) {
            return sortArticles.get(article);
        } else {
            String sort = getSort(cat);
            sortArticles.put(article, sort);
            return sort;
        }
    }

    public static String getSort(String cat) {
        if (catSort.containsKey(cat)) {
            return catSort.get(cat) + "";
        }
        return counter++ + "";
    }

    public static class ModelItem {
        String article;
        String brandName;
        String modelName;
        String name;
        String url;
        String imgUrl;
        int price;
        int count;

        public boolean isAvailable() {
            return count > 0;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            ModelItem modelItem = (ModelItem) o;

            if (url != null ? !url.equals(modelItem.url) : modelItem.url != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            return url != null ? url.hashCode() : 0;
        }

        @Override
        public String toString() {
            return "ModelItem{" +
                    "modelName='" + modelName + '\'' +
                    ", name='" + name + '\'' +
                    ", url='" + url + '\'' +
                    '}';
        }
    }

}
